package com.code.splider.common.interceptor;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import org.springframework.util.StopWatch;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * MethodTimeAdvice .
 *
 * @author zhaoshg
 * @date 2016-3-23
 */
public class MethodTimeAdvice implements MethodInterceptor {

    protected Logger logger = LoggerFactory.getLogger(getClass());


    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        //用 commons-lang 提供的 StopWatch 计时，Spring 也提供了一个 StopWatch
         StopWatch clock = new StopWatch();
        ProxyMethodInvocation proxyInvocation = (ProxyMethodInvocation) invocation;
        clock.start(); //计时开始
        Object result = null;
        //监控的类名
        String className = proxyInvocation.getProxy().getClass().getSimpleName();
        if(className.contains("$")){
            className = className.substring(0,className.indexOf("$"));
        }
        //监控的方法名
        String methodName = className + "." + invocation.getMethod().getName();
        try {
            //这个是我们监控的bean的执行并返回结果
            result = invocation.proceed();
        } catch (Throwable e) {
            //监控的参数
            Object[] objs = invocation.getArguments();
            logger.error("执行异常,方法名：{} , 参数:{} , e = {}", invocation.getArguments(), getString(objs), e);
            throw e;
        }
        clock.stop(); //计时结束
        if (logger.isInfoEnabled()) {
            logger.info("执行时间: {} ms , method = [{}] , params = [{}]", clock.getTotalTimeMillis(), methodName, getString(invocation.getArguments()));
        }
        return result;
    }


    /**
     * 这个类主要是用于输出方法的参数
     *
     * @param objs
     * @return
     */
    @SuppressWarnings("unchecked")
    public String getString(Object[] objs) {
        StringBuffer stringBuffer = new StringBuffer();
        if (objs == null || objs.length < 1) {
            return "";
        }
        for (int i = 0, len = objs.length; i < len; i++) {
            if (null != objs[i])
                stringBuffer.append(objs[i].toString()).append(",");
        }
        return stringBuffer.toString();
    }
}
